#ifndef CLIB_CLIB_CONTAINER_HASH_MAP_H
#define CLIB_CLIB_CONTAINER_HASH_MAP_H

#include <stdbool.h>
#include "../../base/clib_base.h"


CLIB_CPLUS_SUPPORT_START

struct clib_container_hash_map;

struct clib_container_hash_map_conf {
    /**
     * 负载因子决定了bucket表数组的增长方式。
     * 例如，如果负载因子为 0.5，数组容量为 100，则在添加第 50 个条目后将触发调整大小。
     */
    float load_factor;

    /**
     * bucket表数组的初始容量。
     */
    size_t initial_capacity;

    /**
     * 密钥的长度
     */
    int key_length;

    /**
     * 哈希种子
     */
    clib_uint32_t hash_seed;

    /**
     * hash函数
     * @param key key
     * @param length 长度
     * @param seed 种子
     * @return
     */
    size_t (*hash_func)(const void *key, size_t length, clib_uint32_t seed);

    /**
     * 键的比较函数
     * @param key1 键1
     * @param key2 键2
     * @return
     */
    int (*key_compare_func)(const void *key1, const void *key2, size_t key_length);

    /**
     * 内存分配函数
     * @param size 需要分配的大小
     * @return
     */
    void *(*mem_malloc_func)(size_t size);

    /**
     * 内存释放函数
     * @param block 块指针
     */
    void (*mem_free_func)(void *block);

    /**
     * 内存拷贝函数
     * @param target 目标
     * @param src 源
     * @param size 大小
     * @return
     */
    void *(*mem_copy_func)(void *target,const void *src, size_t size);
};

/**
 * 创建hashmap
 * @param conf 配置信息
 * @param map 生成的hashmap对象
 * @return
 * 成功 0
 * 失败 非0
 */
int clib_container_hash_map_create_with_conf(struct clib_container_hash_map_conf *conf,
                                             struct clib_container_hash_map **map);

/**
 * 销毁hashmap
 * @param map 要销毁的hashmap对象
 */
void clib_container_hash_map_destroy(struct clib_container_hash_map *map);


/**
 * 向hashmap中添加一个值
 * @param map hashmap对象
 * @param key 要添加的key
 * @param value 要添加的值
 * @param pre_value 如果key已经存在，则将返回以前的数据指针，如果需要释放，用户需要手动释放，传入NULL，则忽略原来的值
 * @return
 * 成功 0
 * 失败 非0
 */
int clib_container_hash_map_put(struct clib_container_hash_map *map, void *key, void *value, void **pre_value);


/**
 * 删除hashmap的一个值
 * @param map hashmap对象
 * @param key 要删除的key
 * @param out 如果删除成功，存储删除之后的数据指针，该函数不会自动进行释放，需要用户自己释放
 * @return
 * 成功 0
 * 失败 非0
 */
int clib_container_hash_map_remove(struct clib_container_hash_map *map, void *key, void **out);

/**
 * 获取hashmap的一个值
 * @param map hashmap对象
 * @param key 查询的key
 * @param out 查询后的结果
 * @return
 * 成功 0
 * 失败 非0
 */
int clib_container_hash_map_get(struct clib_container_hash_map *map, void *key, void **out);

/**
 * 获取当前hashmap存储的key的个数
 * @param map hashmap对象
 * @return
 * 返回当前存储key的个数
 */
size_t clib_container_hash_map_get_current_size(struct clib_container_hash_map *map);


/**
 * 获取当前hashmap中存储的所有key
 * @param map hashmap对象
 * @param out_keys 存储查询出的所有key
 * @return 返回的key的个数
 */
int clib_container_hash_map_get_keys(struct clib_container_hash_map *map, void **out_keys);


/**
 * 删除所有的节点
 * @param map hashmap对象
 * @param out_values 返回原来存储的数据指针，忽略则传入NULL
 * @return 删除的个数
 */
int clib_container_hash_map_remove_all(struct clib_container_hash_map *map, void *out_values[]);


/**
 * 判断是否含有指定key
 * @param map hashmap对象
 * @param key 要查询的key
 * @return
 */
bool clib_container_hash_map_contains_key(struct clib_container_hash_map *map, void *key);

CLIB_CPLUS_SUPPORT_END


#endif //CLIB_CLIB_CONTAINER_HASH_MAP_H
